<?php
declare (strict_types = 1);

namespace App\Logic;

use App\Event\AdministratorLogsEvent;
use App\Models\Article as ArticleModel;
use App\Models\ArticleContent as ArticleContentModel;
use App\Models\Tags as TagsModel;
use Illuminate\Support\Facades\DB;

class Article
{
    public function count(array $where = [])
    {
        $map[] = ['delete_time', '=', 0];
        if (!empty($where)) {
            if (!empty($where['article_title'])) $map[] = ['article_title', 'like',  '%'.$where['article_title'].'%'];
            if (!empty($where['cate_id'])) $map[] = ['cate_id', '=',  $where['cate_id']];
            if (!empty($where['is_recom'])) $map[] = ['is_recom', '=',  $where['is_recom']];
        }
        return ArticleModel::where($map)->count();
    }

    public function list(int $start, int $limit, array $where = [])
    {
        $map[] = ['delete_time', '=', 0];
        if (!empty($where)) {
            if (!empty($where['article_title'])) $map[] = ['article_title', 'like',  '%'.$where['article_title'].'%'];
            if (!empty($where['cate_id'])) $map[] = ['cate_id', '=',  $where['cate_id']];
            if (!empty($where['is_recom'])) $map[] = ['is_recom', '=',  $where['is_recom']];
        }
        return ArticleModel::with('category')->where($map)->orderBy('id','desc')->offset($start)->limit($limit)->get();
    }

    public function add(array $data)
    {
        $article = new ArticleModel();
        $article->cate_id = $data['cate_id'];
        $article->article_title = $data['article_title'];
        $article->article_img = $data['article_img'];
        $article->read_num = $data['read_num'];
        $article->article_status = $data['article_status'];
        $article->is_recom = $data['is_recom'];

        $content = new ArticleContentModel();
        $content->article_content = $data['article_content'];

        DB::beginTransaction();
        try {
            $article->save();
            $article->content()->save($content);
            if (!empty($data['article_tags'])) $article->tags()->sync($data['article_tags']);
            DB::commit();
            event(new AdministratorLogsEvent("添加文章"));
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            return false;
        }
    }

    public function update(int $id, array $data)
    {
        $article = ArticleModel::find($id);
        $article->cate_id = $data['cate_id'];
        $article->article_title = $data['article_title'];
        $article->article_img = $data['article_img'];
        $article->read_num = $data['read_num'];
        $article->article_status = $data['article_status'];
        $article->is_recom = $data['is_recom'];

        DB::beginTransaction();
        try {
            $article->save();
            $article->content()->where('article_id',$id)->update(['article_content' => $data['article_content']]);
            if (!empty($data['article_tags'])) $article->tags()->sync($data['article_tags']);
            DB::commit();
            event(new AdministratorLogsEvent("修改文章"));
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            return false;
        }
    }

    public function delete(int $id)
    {
        $article = ArticleModel::find($id);
        DB::beginTransaction();
        try {
            $article->content()->delete();
            $article->tags()->detach();
            $article->delete();
            DB::commit();
            event(new AdministratorLogsEvent("删除文章"));
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            return false;
        }
    }

    public function status(int $id)
    {
        $article = ArticleModel::find($id);
        if (!empty($article)) {
            if ($article->article_status == 1){
                $article->article_status = 2;
            }else{
                $article->article_status = 1;
            }
            if ($article->save()){
                event(new AdministratorLogsEvent("修改文章状态"));
                return true;
            }
        }
        return false;
    }

    public function find(int $id)
    {
        return ArticleModel::with('tags')->with('content')->find($id);
    }

    public function has(int $id)
    {
        $model = ArticleModel::find($id);
        if (empty($model)) return false;
        return true;
    }

    public function countByCateId(int $cateId)
    {
        $map[] = ['delete_time', '=', 0];
        $map[] = ['cate_id', '=',  $cateId];
        return ArticleModel::where($map)->count();
    }
}
